package main

import (
	"fmt"
	"reflect"
)

type User struct {
	Name string
	Age  int
	Sex  string
}

func (user User) Say(msg string) {
	fmt.Println("User说：", msg)
}

func (user User) PrintInfo() {
	fmt.Printf("名字：%s 年龄：%d 性别%s", user.Name, user.Age, user.Sex)
}
func main() {
	user := User{
		Name: "小王",
		Age:  19,
		Sex:  "男",
	}
	reflectGetInfo(user)

}

// 反射获取结构体信息
func reflectGetInfo(input interface{}) {
	getType := reflect.TypeOf(input)
	fmt.Println("类型：", getType.Name()) //类型： User
	fmt.Println("种类：", getType.Kind()) //种类： struct  不管是什么结构，类型都是结构体
	//获取值
	getValue := reflect.ValueOf(input)
	fmt.Println(getValue)

	//获取字段和字段值
	//遍历结构体中字段的个数
	for i := 0; i < getType.NumField(); i++ {
		field := getType.Field(i) //分别得到每一个字段的名称 类型
		fmt.Println(field)

		// Interface  获取对应的值
		value := getValue.Field(i).Interface() //获取得到每一个字段的值
		fmt.Printf("字段名：%s 字段类型： %s 字段数值： %v\n", field.Name, field.Type, value)
	}

	//这里有问题！！！！！！！！(解决  再一个包中main方法外的方法名大写才可以被main内部代码得到)
	for i := 0; i < getType.NumMethod(); i++ {
		method := getType.Method(i)
		fmt.Println(method)
		fmt.Printf("方法名称：%s 方法类型：%v\n", method.Name, method.Type)
	}
}
